from PyQt6.QtCore import Qt, pyqtSignal, QRectF
from PyQt6.QtGui import QPainter, QAction, QCursor
from PyQt6.QtWidgets import QWidget, QMenu

from gui.utils import get_pixmap
from gui.utils.colors import DIM_GREY
from gui.utils.size import ZONING_SIZE, RESOURCE_HEIGHT, WORLD_SIZE
from settings import IMAGE_DIR
from state.block import WorldBlock, ZoningBlock
from state.building import Building, BUILDING_MAP
from state.game_state import GameState
from utils.event_bus import EventBus


class PanelZoning(QWidget):
    def __init__(self, state: GameState, parent=None):
        super(PanelZoning, self).__init__(parent)

        self.state = state
        self.select_block: WorldBlock | None = None
        self.w = 1
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.setGeometry(QRectF(WORLD_SIZE, RESOURCE_HEIGHT, ZONING_SIZE - 1, ZONING_SIZE - 1).toRect())

        EventBus.register('update_zoning', self.update)
        EventBus.register('update_zoning_block', self.update_block)

    def paintEvent(self, event):
        painter = QPainter(self)

        if self.select_block is None:
            painter.setPen(Qt.GlobalColor.black)
            painter.setBrush(Qt.GlobalColor.white)
            painter.drawRect(QRectF(0.0, 0.0, ZONING_SIZE - 2, ZONING_SIZE - 2))
        else:
            self.w = (w := ZONING_SIZE / self.select_block.z_number)
            for (row, col), zoning in self.select_block.zoning_map.items():
                painter.setPen(Qt.GlobalColor.black)
                painter.setBrush(Qt.GlobalColor.white)
                rect = QRectF(col * w, row * w, w - 2, w - 2)

                if zoning.occupied is not None:
                    painter.setBrush(DIM_GREY)
                    painter.drawRect(rect)
                    continue
                else:
                    painter.drawRect(rect)

                # 该区划有建筑存在
                if zoning.building is not None:
                    icon_path = str(IMAGE_DIR / 'building' / f'{zoning.building}.png')
                    painter.drawPixmap(rect.toRect(), get_pixmap(icon_path))

    def update_block(self, pos: str):
        if not pos:
            self.select_block = None
        else:
            row, col = pos.split(',')
            self.select_block = self.state.world_block_map[(int(row), int(col))]

        self.update()

    def mouseReleaseEvent(self, event):
        pos = event.pos()
        button = event.button()
        row, col = int(pos.y() / self.w), int(pos.x() / self.w)

        if self.select_block is None:
            return

        zoning: ZoningBlock = self.select_block.zoning_map[(row, col)]
        if button == Qt.MouseButton.RightButton:
            self.create_menu(zoning, zoning.building)
        else:
            EventBus.publish('update_info', zoning.info())

    def create_menu(self, zoning: ZoningBlock, building_name: str | None):
        menu = QMenu(self)

        if building_name is None:
            def __build():
                ...

            action_build = QAction('建造', self)
            action_build.triggered.connect(__build)
            menu.addAction(action_build)
        else:
            building: Building = BUILDING_MAP[building_name]
            if building.next is not None:
                def __upgrade():
                    zoning.building = building.next
                    self.update()

                action_upgrade = QAction('升级', self)
                action_upgrade.triggered.connect(__upgrade)
                menu.addAction(action_upgrade)

            def __destroy():
                zoning.building = None
                self.update()

            action_destroy = QAction('拆除', self)
            action_destroy.triggered.connect(__destroy)
            menu.addAction(action_destroy)

        menu.popup(QCursor.pos())
